using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Reflection;
using DynamiteXml;
using System.Collections;

namespace DynamiteXml.HelperLogic
{
    /// <summary>
    /// This object contains the IDynamiteXml and the DynamiteXmlTypeIdentifier
    /// </summary>
    [Serializable]
    public class Container
    {
        /// <summary>
        /// Public constructor required for deserializing.
        /// </summary>
        public Container()
        {
            //
            // intentionally left blank
            //
        }

        #region Xml object

        private TypeIdentifier dynamiteXmlTypeIdentifier;
        /// <summary>
        /// The identifier class that describes the type and assembly name of the formatter specific xml object
        /// used for this instance.
        /// </summary>
        [XmlElement("Type")]                
        public TypeIdentifier DynamiteXmlTypeIdentifier
        {
            get
            {
                return dynamiteXmlTypeIdentifier;
            }
            set
            {
                dynamiteXmlTypeIdentifier = value;
            }
        }

        private string rawXml;

        private IDynamiteXml xml;

        /// <summary>
        /// The IDynamiteXml that will be serialized using the DynamiteXmlSerializeLogic
        /// </summary>
        [XmlIgnore]
        public IDynamiteXml Xml
        {
            get
            {
                if (xml == null)
                {
                    
                    if ((!string.IsNullOrEmpty(rawXml)) && (dynamiteXmlTypeIdentifier != null))
                    {
                        Assembly assembly = Assembly.Load(dynamiteXmlTypeIdentifier.AssemblyName);
                        using (XmlTextReader reader = new XmlTextReader(new StringReader(rawXml)))
                        {
                            XmlSerializer xmlSerializer = new XmlSerializer(assembly.GetType(dynamiteXmlTypeIdentifier.TypeName));
                            xml = (IDynamiteXml)xmlSerializer.Deserialize(reader);
                        }
                        XmlSafeTextLogic.RevertEnforceXmlSafeText(xml);
                    }
                }

                return xml;
            }
            set
            {
                xml = value;
                #region Get dynamiteXml Type Identifier
                if (xml != null)
                {
                    dynamiteXmlTypeIdentifier = new TypeIdentifier();
                    dynamiteXmlTypeIdentifier.AssemblyName = xml.GetType().Assembly.FullName;
                    dynamiteXmlTypeIdentifier.TypeName = xml.GetType().FullName;
                }
                else
                {
                    dynamiteXmlTypeIdentifier = null;
                }

                #endregion
            }
        }

        /// <summary>
        /// The xml representation of the IDynamiteXml.
        /// Used internally by the DynamiteXmlSerializeLogic
        /// </summary>
        [XmlElement("Data")]
        public Serializer DynamiteXmlSerializer
        {
            get
            {
                Serializer result = null;
                if (xml != null)
                {
                    result = new Serializer(xml);
                }
                else
                {
                    result = null;
                }

                return result;
            }
            set
            {
                if (value != null)
                {
                    rawXml = value.RawXml;
                }
                else
                {
                    rawXml = null;
                }
            }
        }

        #endregion
    }
}
